package com.mall.ware.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.common.constants.WareConstants;
import com.mall.ware.entity.PurchaseDetailEntity;
import com.mall.ware.service.PurchaseDetailService;
import com.mall.ware.service.WareSkuService;
import com.mall.ware.vo.MergeVo;
import com.mall.ware.vo.PurchaseDoneVo;
import com.mall.ware.vo.PurchaseItemDoneVO;
import org.bouncycastle.asn1.x509.GeneralName;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.utils.PageUtils;
import com.common.utils.Query;

import com.mall.ware.dao.PurchaseDao;
import com.mall.ware.entity.PurchaseEntity;
import com.mall.ware.service.PurchaseService;
import org.springframework.transaction.annotation.Transactional;

import javax.management.StandardEmitterMBean;


@Service("purchaseService")
public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService {
    @Autowired
    private PurchaseDetailService purchaseDetailService;

    @Autowired
    private WareSkuService wareSkuService;
    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<PurchaseEntity> page = this.page(
                new Query<PurchaseEntity>().getPage(params),
                new QueryWrapper<PurchaseEntity>()
        );

        return new PageUtils(page);
    }

    /**
     * 查询采购单的状态为新建和以分配的采购单
     * @param params
     * @return
     */
    @Override
    public PageUtils unReceiveList(Map<String, Object> params) {
        Page<PurchaseEntity> page = this.lambdaQuery()
                .eq(PurchaseEntity::getStatus, "0")
                .or()
                .eq(PurchaseEntity::getStatus, "1").page(new Page<>());
        return new PageUtils(page);
    }

    /**
     * 完成采购需求的合单操作
     * @param mergeVo
     * @return
     */
    @Override
    @Transactional
    public Integer merger(MergeVo mergeVo) {
            Long purchaseId = mergeVo.getPurchaseId();
            if(purchaseId == null){
                // 新建采购单
                PurchaseEntity purchaseEntity = new PurchaseEntity();
                purchaseEntity.setStatus(WareConstants.PurchaseStatusEnum.CREATED.getCode());
                purchaseEntity.setCreateTime(new Date());
                purchaseEntity.setUpdateTime(new Date());
                this.save(purchaseEntity);
                purchaseId = purchaseEntity.getId();
            }
        PurchaseEntity purchaseEntity = this.getById(purchaseId);
            if (purchaseEntity.getStatus() <= WareConstants.PurchaseStatusEnum.RECEIVE.getCode()){
                return -1;
            }
        // 整合菜单需求单
            List<Long> items = mergeVo.getItems();
            final long finalPurchaseId = purchaseId;
            List<PurchaseDetailEntity> list = items.stream().map(i -> {
                PurchaseDetailEntity detailEntity = new PurchaseDetailEntity();
                // 更新每一条 需求单的 采购单编号
                detailEntity.setId(i);
                detailEntity.setPurchaseId(finalPurchaseId);
                detailEntity.setStatus(WareConstants.PurchaseDetailStatusEnum.ASSIGED.getCode());
                return detailEntity;
            }).filter(id ->{
                PurchaseDetailEntity item = purchaseDetailService.getById(id);
                if (item.getStatus() == WareConstants.PurchaseDetailStatusEnum.CREATED.getCode() ||
                item.getStatus() == WareConstants.PurchaseDetailStatusEnum.ASSIGED.getCode()){
                    return true;
                }
                return false;
            }).collect(Collectors.toList());
            if (ObjectUtil.isNotNull(list)) {
                purchaseDetailService.updateBatchById(list);
            }
            // 更新对应的采购单的更新时间
            PurchaseEntity entity = new PurchaseEntity();
            entity.setId(purchaseId);
            entity.setUpdateTime(new Date());
            this.updateById(entity);
            return 1;
        }

    /**
     * 领取采购单
     * @param ids
     */
    @Transactional
    @Override
    public void receive(List<Long> ids) {
        // 1.领取的采购单的状态只能是新建或者已分配的采购单 其他的是不能领取的
        List<PurchaseEntity> list = ids.stream().map(id -> {
            return this.getById(id);
        }).filter(item -> {

            if (item.getStatus() == WareConstants.PurchaseStatusEnum.CREATED.getCode() ||
                    item.getStatus() == WareConstants.PurchaseStatusEnum.ASSIGED.getCode()) {

                return true;
            }
            return false;
        }).map(item->{
            item.setUpdateTime(new Date()); // 设置更新时间
            // 更新采购单的状态为 已领取
            item.setStatus(WareConstants.PurchaseStatusEnum.RECEIVE.getCode());
            return item;
        }).collect(Collectors.toList());
        // 2.更新采购单的状态为 已领取
        this.updateBatchById(list);
        // 3.更新采购项的状态为 正在采购

        for (Long id : ids) {
            // 根据采购单id 找到对应的采购项对象
            List<PurchaseDetailEntity> detailEntities = purchaseDetailService.listDetailByPurchaseId(id);
            List<PurchaseDetailEntity> collect = detailEntities.stream().map(item -> {
                PurchaseDetailEntity entity = new PurchaseDetailEntity();
                entity.setId(item.getId());
                entity.setStatus(WareConstants.PurchaseDetailStatusEnum.BUYING.getCode());
                return entity;
            }).collect(Collectors.toList());
            // 批量更新采购项
           purchaseDetailService.updateBatchById(collect);
        }
    }

    @Override
    @Transactional
    public void done(PurchaseDoneVo vo) {
        Long id = vo.getId();
        Boolean flag = true;
        List<PurchaseItemDoneVO> items = vo.getItems();
        List<PurchaseDetailEntity> list = new ArrayList<>();
        for (PurchaseItemDoneVO item : items) {
            PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity();
            if (item.getStatus() == WareConstants.PurchaseDetailStatusEnum.HASERROR.getCode()){
                flag = false;
                purchaseDetailEntity.setStatus(item.getStatus());
            }else {
                purchaseDetailEntity.setStatus(WareConstants.PurchaseDetailStatusEnum.FINISH.getCode());
                PurchaseDetailEntity detailServiceById = purchaseDetailService.getById(item.getItemId());
                wareSkuService.addStock(detailServiceById);
            }
            purchaseDetailEntity.setId(item.getItemId());
            list.add(purchaseDetailEntity);
        }
        purchaseDetailService.updateBatchById(list);
        PurchaseEntity purchaseEntity = new PurchaseEntity();
        purchaseEntity.setId(id);
        purchaseEntity.setStatus(flag ? WareConstants.PurchaseStatusEnum.FINISH.getCode() :
                WareConstants.PurchaseDetailStatusEnum.HASERROR.getCode());
        purchaseEntity.setUpdateTime(new Date());
        this.updateById(purchaseEntity);
    }

}